<?php

namespace common\widgets;

use Yii;
use yii\helpers\Url;
use common\helpers\Html;
use common\helpers\ArrayHelper;
use yii\helpers\Inflector;
use kartik\date\DatePicker;
use kartik\datetime\DateTimePicker;

/**
 * A Bootstrap 3 enhanced version of [[\yii\widgets\ActiveField]].
 *
 * @see \yii\bootstrap\ActiveForm
 * @see http://getbootstrap.com/css/#forms
 *
 * @author Michael Härtl <haertl.mike@gmail.com>
 * @since 2.0
 */
class ActiveField extends \yii\bootstrap\ActiveField {

    /**
     * @var bool whether to render [[checkboxList()]] and [[radioList()]] inline.
     */
    public $inline = false;

    /**
     * @var string|null optional template to render the `{input}` placeholder content
     */
    public $inputTemplate;

    /**
     * @var array options for the wrapper tag, used in the `{beginWrapper}` placeholder
     */
    public $wrapperOptions = [];

    /**
     * @var null|array CSS grid classes for horizontal layout. This must be an array with these keys:
     *  - 'offset' the offset grid class to append to the wrapper if no label is rendered
     *  - 'label' the label grid class
     *  - 'wrapper' the wrapper grid class
     *  - 'error' the error grid class
     *  - 'hint' the hint grid class
     */
    public $horizontalCssClasses = [
        'offset' => 'col-md-offset-2 col-sm-offset-3 col-xs-offset-2',
        'label' => 'col-md-2 col-sm-3 col-xs-12',
        'wrapper' => 'col-md-10 col-sm-9 col-xs-12',
        'error' => '',
        'hint' => 'col-sm-offset-3 col-sm-9 text-hint-info',
    ];

    /**
     * @var string the template that is used to arrange the label, the input field, the error message and the hint text.
     * The following tokens will be replaced when [[render()]] is called: `{label}`, `{input}`, `{error}` and `{hint}`.
     */
    public $template = "{label}\n{beginWrapper}\n{input}\n{error}\n{hint}\n{endWrapper}";

    /**
     * @var string the template for checkboxes in default layout
     */
    public $checkboxTemplate = "<label class=\"mt-checkbox mt-checkbox-outline\">\n{input}\n{labelTitle}<span></span>\n{endLabel}\n{error}\n{hint}";

    /**
     * @var string the template for radios in default layout
     */
    public $radioTemplate = "<div class=\"radio\">\n{beginLabel}\n{input}\n{labelTitle}\n{endLabel}\n{error}\n{hint}\n</div>";

    /**
     * @var string the template for checkboxes in horizontal layout
     */
    public $horizontalCheckboxTemplate = "<div class=\"col-md-offset-3 col-md-4\">\n<label class=\"mt-checkbox mt-checkbox-outline\">\n{input}\n{labelTitle}<span></span>\n{endLabel}\n{error}\n{hint}\n</div>";

    /**
     * @var string the template for radio buttons in horizontal layout
     */
    public $horizontalRadioTemplate = "{beginWrapper}\n<div class=\"radio\">\n{beginLabel}\n{input}\n{labelTitle}\n{endLabel}\n</div>\n{error}\n{endWrapper}\n{hint}";

    /**
     * @var string the template for inline checkboxLists
     */
    public $inlineCheckboxListTemplate = "{label}\n{beginWrapper}\n{input}\n{error}\n{hint}\n{endWrapper}";

    /**
     * @var string the template for inline radioLists
     */
    public $inlineRadioListTemplate = "{label}\n{beginWrapper}\n{input}\n{error}\n{hint}\n{endWrapper}";

    /**
     * @var bool whether to render the error. Default is `true` except for layout `inline`.
     */
    public $enableError = true;

    /**
     * @var bool whether to render the label. Default is `true`.
     */
    public $enableLabel = true;

    /**
     * {@inheritdoc}
     */
    protected function getItems($fill = null) {
        $items = [];
        $model = $this->model;
        $property = Inflector::variablize($this->attribute) . 'List';
        if ($model->hasProperty($property)) {
            $items = $model->$property;
        } elseif ($model->hasMethod('getOptionList')) {
            $items = $model::getOptionList($this->attribute, $fill);
        }
        if (empty($items) && $model->hasMethod('getConstants')) {
            $items = $model::getConstAttributeLabels($this->attribute, $fill);
        }
        return $items;
    }

    public function textInput($options = []) {
        $class = ArrayHelper::remove($options, 'class');
        Html::addCssClass($this->inputOptions, $class);

        $options['placeholder'] = $this->model->getAttributeLabel($this->attribute);

        return parent::textInput($options);
    }

    /**
     * {@inheritdoc}
     */
    public function radioList($items = null, $options = []) {
        if ($items === null) {
            $items = $this->getItems('<span></span>');
        }
        $removeItemValue = ArrayHelper::getValue($options, 'remove_item_value');
        if ($removeItemValue !== null) {
            ArrayHelper::remove($items, $removeItemValue);
        }
        $defaultOptions = ArrayHelper::merge([
            'class' => 'mt-radio-inline',
            'encode' => false,
            'itemOptions' => [
                'labelOptions' => ['class' => 'mt-radio mt-radio-outline'],
            ],
        ], $options);
        return parent::radioList($items, $defaultOptions);
    }

    /**
     * {@inheritdoc}
     */
    public function checkboxList($items = null, $options = []) {
        if ($items === null) {
            $items = $this->getItems('<span></span>');
        }
        $removeItemValue = ArrayHelper::getValue($options, 'remove_item_value');
        if ($removeItemValue !== null) {
            ArrayHelper::remove($items, $removeItemValue);
        }
        $defaultOptions = ArrayHelper::merge([
            'class' => 'mt-checkbox-inline',
            'encode' => false,
            'itemOptions' => [
                'labelOptions' => ['class' => 'mt-checkbox mt-checkbox-outline'],
            ],
        ], $options);
        return parent::checkboxList($items, $defaultOptions);
    }

    /**
     * {@inheritdoc}
     */
    public function dropDownList($items = null, $options = []) {
        if ($items == null) {
            $items = $this->getItems();
        }
        $defaultValue = ArrayHelper::remove($options, 'default', 0);
        $defaultOptions = ArrayHelper::merge([
            'prompt' => [
                'text' => '请选择...',
                'options' => [
                    'value' => $defaultValue
                ]
            ],
        ], $options);
        return parent::dropDownList($items, $defaultOptions);
    }

    /**
     * {@inheritdoc}
     */
    public function address($options = []) {
        if ($this->inputOptions) {
            $options['options'] = $this->inputOptions;
        }
        return $this->widget(\common\widgets\address\AddressInput::className(), $options);
    }

    /**
     * {@inheritdoc}
     */
    public function distpicker($options = []) {
        if ($this->inputOptions) {
            $options['options'] = $this->inputOptions;
        }
        return $this->widget(\common\widgets\distpicker\DistpickerInput::className(), $options);
    }

    /**
     * {@inheritdoc}
     */
    public function selectMulti($items = null, $options = []) {
        if ($items == null) {
            $items = $this->getItems();
        }
        if ($this->inputOptions) {
            $options['options'] = $this->inputOptions;
        }
        $options['data'] = $items;
        return $this->widget(\common\widgets\Select2Input::className(), $options);
    }

    /**
     * {@inheritdoc}
     */
    public function selectSplitter($items = null, $options = []) {
        if ($this->inputOptions) {
            $options['options'] = $this->inputOptions;
        }
        return $this->widget(\common\widgets\SelectSplitterInput::className(), $options);
    }

    /**
     * {@inheritdoc}
     */
    public function colorPicker($options = []) {
        if ($this->inputOptions) {
            $options['options'] = $this->inputOptions;
        }
        return $this->widget(\common\widgets\colorpicker\ColorPickerInput::className(), $options);
    }

    /**
     * {@inheritdoc}
     */
    public function cropImage($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        $type = ArrayHelper::remove($options, 'type', 'default');
        return $this->widget(\emhome\jcrop\Jcrop::className(), ArrayHelper::merge([
            'uploadUrl' => Url::to(['/attachs/jcrop', 'type' => $type]),
        ], $options));
    }

    /**
     * {@inheritdoc}
     */
    public function video($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        return $this->widget(\youmbe\plupload\src\Plupload::className(), ArrayHelper::merge([
            'url' => ['/attachs/plupload'],
            'attachUrl' => Yii::getAlias('@attachUrl'),
            'ratio' => 2,
        ], $options));
    }

    /**
     * {@inheritdoc}
     */
    public function uploadFile($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        return $this->widget(\emhome\plupload\Plupload::className(), ArrayHelper::merge([
            'url' => ['/attachs/plupload'],
            'attachUrl' => Yii::getAlias('@attachUrl'),
            'resize' => ['width' => 200, 'height' => 200],
            'options' => [
                'multipart_params' => ['dir' => 'default'],
            ],
        ], $options));
    }

    /**
     * {@inheritdoc}
     */
    public function gallery($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        return $this->widget(\youmbe\plupload\widget\Gallery::className(), ArrayHelper::merge([
            'url' => ['/attachs/plupload'],
            'attachUrl' => Yii::getAlias('@attachUrl'),
            'options' => [
                'multipart_params' => ['dir' => 'default'],
            ],
        ], $options));
    }

    /**
     * {@inheritdoc}
     */
    public function editor($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        return $this->widget(\common\widgets\ueditor\UEditor::className(), $options);
    }

    /**
     * {@inheritdoc}
     */
    public function daterange($options = []) {
        $class = ArrayHelper::remove($options, 'class', 'input-medium');
        Html::addCssClass($this->inputOptions, $class);
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        $value = $this->model->{$this->attribute};
        if (is_numeric($value)) {
            $this->model->{$this->attribute} = date('Y-m-d', $value);
        }
        return $this->widget(DatePicker::className(), ArrayHelper::merge([
            'size' => 'medium',
            'options' => [
                'placeholder' => $this->model->getAttributeLabel($this->attribute),
                'autocomplete' => 'off',
            ],
            'language' => 'zh-CN',
            'type' => DatePicker::TYPE_RANGE,
            'pluginOptions' => [
                'autoclose' => true,
                'todayHighlight' => true,
                'format' => 'yyyy-mm-dd',
            ]
        ], $options));
    }

    /**
     * {@inheritdoc}
     */
    public function date($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        $value = $this->model->{$this->attribute};
        if (is_numeric($value)) {
            $this->model->{$this->attribute} = date('Y-m-d', $value);
        }
        return $this->widget(DatePicker::className(), ArrayHelper::merge([
            'layout' => '{input}{remove}',
            'size' => 'medium',
            'removeIcon' => '<i class="ionicons ion-close-round"></i>',
            'options' => [
                'placeholder' => $this->model->getAttributeLabel($this->attribute),
                'autocomplete' => 'off',
            ],
            'pluginOptions' => [
                'autoclose' => true,
                'todayHighlight' => true,
                'format' => 'yyyy-mm-dd',
            ]
        ], $options));
    }

    /**
     * {@inheritdoc}
     */
    public function datetime($options = []) {
        if ($this->inputOptions) {
            $options = ArrayHelper::merge($options, [
                'options' => $this->inputOptions,
            ]);
        }
        $value = $this->model->{$this->attribute};
        if (is_numeric($value)) {
            $this->model->{$this->attribute} = date('Y-m-d H:i:s', $value);
        }
        return $this->widget(DateTimePicker::className(), ArrayHelper::merge([
            'layout' => '{input}{picker}',
            'size' => 'medium',
            'options' => [
                'placeholder' => $this->model->getAttributeLabel($this->attribute),
                'autocomplete' => 'off',
            ],
            'language' => 'zh-CN',
            'type' => DateTimePicker::TYPE_INPUT,
            'pluginOptions' => [
                'autoclose' => true,
                'todayHighlight' => true,
                'format' => 'yyyy-mm-dd hh:ii:ss',
            ]
        ], $options));
    }

}
